package come.example.domain.strategy.service.raffle;

import come.example.domain.strategy.model.entity.StrategyAwardEntity;
import come.example.domain.strategy.model.vo.RuleTreeVO;
import come.example.domain.strategy.model.vo.StrategyAwardRuleModelVO;
import come.example.domain.strategy.model.vo.StrategyAwardStockKeyVO;
import come.example.domain.strategy.repository.IStrategyRepository;
import come.example.domain.strategy.service.AbstractRaffleStrategy;
import come.example.domain.strategy.service.IRaffleAward;
import come.example.domain.strategy.service.IRaffleStock;
import come.example.domain.strategy.service.armory.IStrategyDispatch;
import come.example.domain.strategy.service.rule.chain.ILogicChain;
import come.example.domain.strategy.service.rule.chain.factory.DefaultChainFactory;
import come.example.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import come.example.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;

@Slf4j
@Service
public class DefaultRaffleStrategy extends AbstractRaffleStrategy implements IRaffleAward, IRaffleStock {


    public DefaultRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch, DefaultChainFactory defaultChainFactory, DefaultTreeFactory defaultTreeFactory) {
        super(repository, strategyDispatch, defaultChainFactory, defaultTreeFactory);
    }

    // 1. 拿到奖品ID
    @Override
    public DefaultChainFactory.StrategyAwardVO raffleLogicChain(String userId, Long strategyId) {
        ILogicChain logicChain = defaultChainFactory.openLogicChain(strategyId);
        return logicChain.logic(userId, strategyId);
    }

    //2. 看奖品ID能不能拿到手
    @Override
    public DefaultTreeFactory.StrategyAwardVO raffleLogicTree(String userId, Long strategyId, Integer awardId) {
        StrategyAwardRuleModelVO strategyAwardRuleModelVO = repository.queryStrategyAwardRuleModel(strategyId, awardId);
        // 如果没有配置规则，就不做过滤了，直接返回奖品
        if(null == strategyAwardRuleModelVO) {
            return DefaultTreeFactory.StrategyAwardVO.builder().awardId(awardId).build();
        }
        RuleTreeVO ruleTreeVO = repository.queryRuleTreeVOByTreeId(strategyAwardRuleModelVO.getRuleModels());

        // 如果规则树里找不到这个规则（库表里没有配置）
        if(null == ruleTreeVO) {
            throw new RuntimeException("存在抽奖策略配置的规则模型 Key，未在库表 rule_tree, rule_tree_node, rule_tree_line配置对应的规则树信息");
        }

        // 规则树
        IDecisionTreeEngine treeEngine = defaultTreeFactory.openLogicTree(ruleTreeVO);
        return treeEngine.process(userId, strategyId, awardId);
    }


    @Override
    public StrategyAwardStockKeyVO takeQueueValue() throws InterruptedException {
        return repository.takeQueueValue();
    }

    /**
     * 更新数据库的值
     *
     * @param strategyId
     * @param awardId
     */
    @Override
    public void updateStrategyAwardStock(Long strategyId, Integer awardId) {
        repository.updateStrategyAwardStock(strategyId, awardId);
    }

    @Override
    public List<StrategyAwardEntity> queryRaffleStrategyAwardList(Long strategyId) {
        return repository.queryStrategyAwardList(strategyId);
    }
}
